package mqigdcom.mqigd.ui;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.Gravity;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

import mqigdcom.mqigd.CustomApp;
import mqigdcom.mqigd.R;
import mqigdcom.mqigd.core.SyncDataService;
import mqigdcom.mqigd.db.IMQIDao;
import mqigdcom.mqigd.db.MQIDaoImpl;
import mqigdcom.mqigd.db.RoadCondition;
import mqigdcom.mqigd.utils.Utils;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.ref.WeakReference;

/**
 * Html页面与本地Js交互类
 */
public class HtmlJsInteraction {

    private WeakReference<MainWebActivity> refer;// 软引用
    private IMQIDao dao;// 数据库的操作接口实例
    private volatile boolean isUpdatingData;// 是否正在更新数据
    private UpdateAllRoadListThread updateAllRoadListThread;// 更新全部数据的线程
    private String strUserHead;// 用户登录后的头像base64之后的数据
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            return false;
        }
    });

    HtmlJsInteraction(MainWebActivity activity) {
        refer = new WeakReference<>(activity);
        dao = new MQIDaoImpl(activity);
    }

    /**
     * 检测软引用的Activity是否可用
     *
     * @return true 可用；false 不可用
     */
    private boolean checkReferAvailable() {
        return refer != null && refer.get() != null && !refer.get().isFinishing();
    }

    /**
     * 释放对象
     */
    public void release() {
        dao.release();
        dao = null;
        strUserHead = null;
        isUpdatingData = false;
        updateAllRoadListThread = null;
    }


    /**
     * 更新全部的公路信息集合，（大量数据）需在子线程中运行
     */
    private class UpdateAllRoadListThread extends Thread {

        String userid;
        String json;

        UpdateAllRoadListThread(String userid, String json) {
            this.userid = userid;
            this.json = json;
        }

        @Override
        public void run() {
            if (!TextUtils.isEmpty(json) && dao != null && !isUpdatingData) {
                try {
                    isUpdatingData = true;
                    dao.updateAllRoadList(userid, new JSONArray(json));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                isUpdatingData = false;
            }
        }
    }

    /**
     * 判断是否正在更新数据
     *
     * @return true 正在更新中；false 没有更新
     */
    public boolean isUpdatingData() {
        return isUpdatingData;
    }

    @JavascriptInterface
    public boolean checkNetworkAvailable() {
        return checkNetworkAvailable(true);
    }

    @JavascriptInterface
    public boolean checkNetworkAvailable(boolean isShowTips) {
        if (checkReferAvailable()) {
            boolean available = Utils.isNetworkAvailable(refer.get());
            if (!available && isShowTips) {
                refer.get().showToast(refer.get().getString(R.string.network_not_available_and_check_to_retry),
                        Toast.LENGTH_SHORT, Gravity.BOTTOM);
            }
            return available;
        }
        return false;
    }

    @JavascriptInterface
    public boolean isDataEmpty(String userid) {
        return dao == null || TextUtils.isEmpty(userid) || dao.isEmpty(userid);
    }

    @JavascriptInterface
    public String getAllRoadList(String userid, boolean needAllFields) {
        return getAllRoadList(userid, needAllFields, true);
    }

    @JavascriptInterface
    public String getAllRoadList(String userid, boolean needAllFields, boolean needUnitList) {
//        String result = "{\"road_list\":" + (dao != null && !TextUtils.isEmpty(userid) ?
//                dao.getAllRoadList(userid, needAllFields, needUnitList) : "[]") + "}";
//        Utils.saveTextToFile(refer.get(), result, "road_list.json");
//        return result;
        return "{\"road_list\":" + (dao != null && !TextUtils.isEmpty(userid) ?
                dao.getAllRoadList(userid, needAllFields, needUnitList) : "[]") + "}";
    }

    @JavascriptInterface
    public void updateAllRoadList(String userid, String json) {
        if (dao != null && !TextUtils.isEmpty(userid) && !TextUtils.isEmpty(json)) {
            if (updateAllRoadListThread != null) {
                if (isUpdatingData) {
                    return;
                }
                updateAllRoadListThread = null;
            }
            updateAllRoadListThread = new UpdateAllRoadListThread(userid, json);
            updateAllRoadListThread.start();
        }
    }

    @JavascriptInterface
    public String getRoadConditionsById(String userid, String road_id, String unit_id, String line_dir, String type) {
        return "{\"list100\":" + (dao != null && !TextUtils.isEmpty(userid) ?
                dao.getRoadConditionsById(userid, road_id, unit_id, line_dir, type) : "[]") + "}";
    }

    @JavascriptInterface
    public void updateRoadCondition(String json) {
        if (dao != null && !TextUtils.isEmpty(json)) {
            try {
                dao.updateOrCreateRoadCondition(new Gson().fromJson(json, RoadCondition.class));
                if (checkReferAvailable()) {
                    Intent intent = new Intent(refer.get(), SyncDataService.class);
                    refer.get().startService(intent);
                }
            } catch (JsonSyntaxException e) {
                e.printStackTrace();
            }
        }
    }

    @JavascriptInterface
    public void clearAllRoadList(String userid) {
        if (dao != null && !TextUtils.isEmpty(userid)) {
            dao.clearAllRoadList(userid);
        }
    }

    @JavascriptInterface
    public void showLoading() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (checkReferAvailable()) {
                    refer.get().mFlagAutoCloseLoading = false;
                    refer.get().setLoadingVisible(true);
                }
            }
        });
    }

    @JavascriptInterface
    public void closeLoading() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (checkReferAvailable()) {
                    refer.get().mFlagAutoCloseLoading = true;
                    refer.get().setLoadingVisible(false);
                }
            }
        });
    }

    @JavascriptInterface
    public void saveUserHead(String userHead) {
        strUserHead = userHead;
    }

    @JavascriptInterface
    public String getUserHead() {
        return Utils.checkNull(strUserHead);
    }


    @JavascriptInterface
    public void loadLocalData() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (checkReferAvailable()) {
                    refer.get().showToast(refer.get().getString(R.string.network_not_available_and_show_offline_data),
                            Toast.LENGTH_LONG, Gravity.BOTTOM);
                    refer.get().loadLocalData();
                }
            }
        });
    }

    @JavascriptInterface
    public void loadLocalRoadSurvey() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (checkReferAvailable()) {
                    refer.get().showToast(refer.get().getString(R.string.network_not_available_and_offline_work),
                            Toast.LENGTH_LONG, Gravity.CENTER);
                    refer.get().loadLocalRoadSurvey();
                }
            }
        });
    }

    @JavascriptInterface
    public String getUserId() {
        String cookie = Utils.getCookieByDomain(MainWebActivity.HTTP_DOMAIN, "login");
        try {
            JSONObject object = new JSONObject(cookie);
            return object.getString("userid");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
    }

    @JavascriptInterface
    public int getStatusBarHeight() {
        return checkReferAvailable() && refer.get().mStatusBarHeight > 0 ? Utils.px2dip(refer.get(), refer.get().mStatusBarHeight) : 0;
    }

    @JavascriptInterface
    public void goBack() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (checkReferAvailable()) {
                    refer.get().goBackPage();
                }
            }
        });
    }

    @JavascriptInterface
    public String getLocalDataSavedTime(String userid) {
        return !TextUtils.isEmpty(userid) ? CustomApp.self.sp.getString(userid, "") : "";
    }

    @JavascriptInterface
    public void getCurrentLocation() {
//        handler.post(new Runnable() {
//            @Override
//            public void run() {
//                if (checkReferAvailable()) {
//                    refer.get().getCurrentLocation();
//                }
//            }
//        });
    }

    @JavascriptInterface
    public void setFlagEnteredRoadConditionSearch(boolean flag) {
        if (checkReferAvailable()) {
            refer.get().mFlagEnteredRoadConditionSearch = flag;
        }
    }
}
